package com.moonLight.weblog.admin.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.moonLight.weblog.admin.model.vo.tag.*;
import com.moonLight.weblog.admin.service.AdminTagService;
import com.moonLight.weblog.common.domain.dos.TArticleTagRelDo;
import com.moonLight.weblog.common.domain.dos.TagDO;
import com.moonLight.weblog.common.domain.mapper.TArticleTagMapper;
import com.moonLight.weblog.common.domain.mapper.TagMapper;
import com.moonLight.weblog.common.enums.ResponseCodeEnum;
import com.moonLight.weblog.common.exception.BizException;
import com.moonLight.weblog.common.model.vo.SelectRspVO;
import com.moonLight.weblog.common.utils.PageResponse;
import com.moonLight.weblog.common.utils.Response;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.concurrent.ConcurrentUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
@Slf4j
public class AdminTagServiceImpl extends ServiceImpl<TagMapper, TagDO> implements AdminTagService {

    @Autowired
    private TagMapper tagMapper;

    @Autowired
    private TArticleTagMapper tArticleTagMapper;

    @Override
    public Response<Void> addTag(AddTagVo addTagVo) {

        List<String> tags = addTagVo.getTags();
        //批量插入到数据库中去 使用 mybatis-plus中的Service Impl中的方法saveBatch(伪批量插入 实际是一条条插入)
        //不涉及到高并发所以不需要太高性能
        // Vo 转 Do
        List<TagDO> tagDOList = tags.stream()
                .filter(tag -> !tag.isEmpty()) // 过滤掉空标签
                .map(tag -> TagDO.builder()
                        .name(tag)
                        .createTime(LocalDateTime.now())
                        .updateTime(LocalDateTime.now())
                        .build())
                .collect(Collectors.toList());
        //批量插入 因为标签名字是唯一索引 所以重复汇报异常
        try{
            saveBatch(tagDOList);
        }catch (Exception e){
            log.warn("标签重复的时候报错" + ResponseCodeEnum.TAG_CANT_DUPLICATE);
        }


        return Response.success();
    }

    @Override
    public Response<List<FindTagPageListRspVo>> findTagPageList(FindTagPageListReqVo findTagPageListReqVo) {
        Long current = findTagPageListReqVo.getCurrent();
        Long size = findTagPageListReqVo.getSize();
        Page<TagDO> tagDOPage = tagMapper.selectPage(current, size, findTagPageListReqVo.getName(), findTagPageListReqVo.getStartDate(), findTagPageListReqVo.getEndDate());

        List<TagDO> records = tagDOPage.getRecords();
        List<FindTagPageListRspVo> vos = null;

        if (!CollectionUtils.isEmpty(records)){
            //Do 转 Vo
            vos  = records.stream().map(
                    tagDO -> FindTagPageListRspVo.builder()
                            .id(tagDO.getId())
                            .name(tagDO.getName())
                            .createTime(tagDO.getCreateTime())
                            .updateTime(tagDO.getUpdateTime())
                            .articlesTotal(tagDO.getArticlesTotal())
                            .build()
            ).collect(Collectors.toList());
        }
        return PageResponse.success(tagDOPage, vos);
    }

    /**
     * 删除标签
     * 1. 先看关联表中该标签是否有文章使用
     * 2.没有则删除
     * 3.有责报错
     * @param deleteTagReqVO
     * @return
     */
    @Override
    public Response<Void> deleteTag(DeleteTagReqVO deleteTagReqVO) {
        Long tagId = deleteTagReqVO.getId();

        TArticleTagRelDo tArticleTagRelDo = tArticleTagMapper.selectOneByTagId(tagId);

        if (Objects.nonNull(tArticleTagRelDo)){
            log.warn("==> 此标签下包含文章，无法删除，tagId: {}", tagId);
            throw new BizException(ResponseCodeEnum.TAG_CAN_NOT_DELETE);
        }
        int count = tagMapper.deleteById(tagId);
        return count == 1 ? Response.success() : Response.fail(ResponseCodeEnum.TAG_NOT_EXISTED);
    }

    @Override
    public Response<List<TagVo>> findTagSelectList() {
        List<TagDO> tagDOS = tagMapper.selectList(Wrappers.emptyWrapper());
        //Do 转 Vo
        List<TagVo> Vos = null;
        if (!CollectionUtils.isEmpty(tagDOS)){
            Vos = tagDOS.stream().map(tagDO -> TagVo.builder()
                    .name(tagDO.getName())
                    .build()).collect(Collectors.toList());
        }
        return Response.success(Vos);
    }

    @Override
    public Response<List<String>> searchTag(SearchTagReqVo searchTagReqVo) {
        LambdaQueryWrapper<TagDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(TagDO::getName, searchTagReqVo.getKey());

        List<TagDO> tagDOList = tagMapper.selectList(wrapper);
        List<String> Vos = null;

        if (!CollectionUtils.isEmpty(tagDOList)){
            Vos = tagDOList.stream().map(tagDO -> tagDO.getName()).collect(Collectors.toList());
        }

        return Response.success(Vos);
    }


}
